import os
import sys
from jili.it import ip0,ip2
from jili.core.printlog import print
from minio import Minio
from minio.error import S3Error
class minio_client:
    def __init__(self, endpoint, access_key, secret_key, secure=True):
        """初始化 MinIO 客户端"""
        self.root="jili"
        self.client = Minio(endpoint, access_key, secret_key, secure=secure)
    def create_bucket_if_not_exists(self, bucket_name):
        """检查存储桶是否存在，不存在则创建"""
        try:
            if not self.client.bucket_exists(bucket_name):
                self.client.make_bucket(bucket_name)
                print(f"创建存储桶: {bucket_name}")
            else:
                print(f"存储桶已存在: {bucket_name}")
        except S3Error as e:
            print("error",f"创建存储桶失败: {e}")
            raise
    def get_file_size(self, object_name,file=""):
        if file != "":
            object_name = file + "/" + object_name
        try:
            # 获取对象的元数据
            stat = self.client.stat_object(self.root, object_name)

            # 返回文件大小（字节）
            return stat.size

        except S3Error as e:
            print(f"获取文件大小失败: {e}")
            return None
    def upload_file(self,file_path, object_name=None,file=""):
        """上传文件到 MinIO"""
        try:
            # 确保存储桶存在
            # self.create_bucket_if_not_exists(self.root)
            # 如果未指定对象名，使用文件名
            if object_name is None:
                object_name = os.path.basename(file_path)
            if file!="":
                object_name=file+"/"+object_name

            # 检查文件是否存在
            if not os.path.isfile(file_path):
                print("error",f"文件不存在: {file_path}")
                return False

            # 上传文件
            self.client.fput_object(self.root, object_name, file_path)
            print(f"文件上传成功: {file_path} -> {self.root}/{object_name}")
            return True
        except S3Error as e:
            print("error",f"文件上传失败: {e}")
            return False
        except Exception as e:
            print("error",f"发生未知错误: {e}")
            return False

    def download_file(self,object_name, file_path=None,file=""):
        """从 MinIO 下载文件"""
        try:
            # 如果未指定文件路径，使用对象名作为文件名
            if file!="":
                object_name=file+"/"+object_name
            if file_path is None:
                file_path = os.path.basename(object_name)

            # 检查存储桶是否存在
            if not self.client.bucket_exists(self.root):
                print("error",f"存储桶不存在: {self.root}")
                return False

            # 检查对象是否存在
            try:
                self.client.stat_object(self.root, object_name)
            except S3Error as e:
                print("error",f"对象不存在: {self.root}/{object_name}")
                return False

            # 下载文件
            self.client.fget_object(self.root, object_name, file_path)
            print(f"文件下载成功: {self.root}/{object_name} -> {file_path}")
            return True
        except S3Error as e:
            print("error",f"文件下载失败: {e}")
            return False
        except Exception as e:
            print("error",f"发生未知错误: {e}")
            return False

    def delete_file(self,object_name,file=""):
        if file!="":
            object_name=file+"/"+object_name
        try:
            # 检查桶是否存在
            if not self.client.bucket_exists(self.root):
                raise Exception(f"桶 {self.root} 不存在")

            # 检查对象是否存在
            try:
                self.client.stat_object(self.root, object_name)
            except S3Error as e:
                if e.code == "NoSuchKey":
                    raise Exception(f"对象 {object_name} 不存在")
                else:
                    raise

            # 执行删除
            self.client.remove_object(self.root, object_name)
            return True, "删除成功"

        except S3Error as e:
            error_msg = f"MinIO错误: {e.message}"
            if e.code == "AccessDenied":
                error_msg += " (权限不足)"
            return False, error_msg

        except Exception as e:
            return False, str(e)

    def list_objects(self, file="", prefix=None, recursive=True):
        """列出存储桶中的对象"""
        try:
            # 检查存储桶是否存在
            if not self.client.bucket_exists(self.root):
                print("error",f"存储桶不存在: {self.root}")
                return []
            if file!="":
                if prefix is None:
                    prefix=file+"/"
                else:
                    prefix=file+"/"+prefix
            # 列出对象
            objects = self.client.list_objects(self.root, prefix=prefix, recursive=recursive)
            if file!="":
                l = [obj.object_name.split("/")[1] for obj in objects]
            else:
                l= [obj.object_name for obj in objects]
            return l
        except S3Error as e:
            print("error",f"列出对象失败: {e}")
            return []
        except Exception as e:
            print("error",f"发生未知错误: {e}")
            return []
# endpoint = os.getenv('MINIO_ENDPOINT', 'play.min.io')
# access_key = os.getenv('MINIO_ACCESS_KEY', 'Q3AM3UQ867SPQQA43P2F')
# secret_key = os.getenv('MINIO_SECRET_KEY', 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG')
# secure = os.getenv('MINIO_SECURE', 'True').lower() == 'true'

# 创建 MinIO 客户端
minio_tool2 = minio_client(endpoint=ip0+":9000", access_key="jili", secret_key="80a3a030-8c7e-43f2-9f82-98d871cbb749", secure=False)
minio_tool= minio_client(endpoint=ip2+":9000", access_key="jili", secret_key="80a3a030-8c7e-43f2-9f82-98d871cbb749", secure=False)

if __name__ == "__main__":
    def main0():
        """主函数，提供命令行交互"""
        print("=== MinIO 文件上传下载工具 ===")

        # 从环境变量获取 MinIO 配置，或使用默认值

        while True:
            print("\n请选择操作:")
            print("1. 上传文件")
            print("2. 下载文件")
            print("3. 列出存储桶中的对象")
            print("4. 退出")

            choice = input("请输入选项 (1-4): ").strip()

            if choice == '1':
                bucket_name = input("请输入存储桶名称: ").strip()
                file_path = input("请输入本地文件路径: ").strip()
                object_name = input("请输入对象名称 (可选，留空则使用文件名): ").strip() or None

                if minio_tool.upload_file(file_path, object_name,bucket_name):
                    print("上传成功!")
                else:
                    print("上传失败!")

            elif choice == '2':
                bucket_name = input("请输入存储桶名称: ").strip()
                object_name = input("请输入对象名称: ").strip()
                file_path = input("请输入本地保存路径 (可选，留空则使用对象名): ").strip() or None

                if minio_tool.download_file(object_name, file_path,bucket_name):
                    print("下载成功!")
                else:
                    print("下载失败!")

            elif choice == '3':
                bucket_name = input("请输入存储桶名称: ").strip()
                prefix = input("请输入前缀 (可选，留空则列出所有对象): ").strip() or None
                print("file",bucket_name,"prefix",prefix)
                objects = minio_tool.list_objects(file=bucket_name, prefix=prefix)
                if objects:
                    print(f"存储桶 {bucket_name} 中的对象:")
                    for obj in objects:
                        print(f"- {obj}")
                else:
                    print(f"存储桶 {bucket_name} 中没有对象或发生错误。")
            elif choice == '4':
                bucket_name = input("请输入存储桶名称: ").strip()
                object_name = input("请输入对象名称: ").strip()
                r,msg=minio_tool.delete_file(object_name,bucket_name)
                if r:
                    print("删除成功!")
                else:
                    print("删除失败!",msg)
            elif choice == '5':
                print("感谢使用! 再见。")
                break

            else:
                print("无效的选项，请重新输入。")
    main0()